home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / CNews / Source / rna / header.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-20  |  7.6 KB  |  378 lines

  1. /*
  2.  * extract/output headers
  3.  */
  4.  
  5. #include "defs.h"
  6. #include <sys/timeb.h>
  7.  
  8. extern char systemid[];
  9. extern long now;
  10.  
  11. char hform[]         = "%s: %s\n";
  12.  
  13. /* Mandatory Headers */
  14. char t_relayversion[]     = "Relay-Version";
  15. char t_postversion[]     = "Posting-Version";
  16. char t_from[]         = "From";
  17. char t_date[]         = "Date";
  18. char t_newsgroups[]     = "Newsgroups";
  19. char t_subject[]     = "Subject";
  20. char t_messageid[]     = "Message-ID";
  21. char t_path[]         = "Path";
  22.  
  23. /* Optional Headers */
  24. char t_replyto[]     = "Reply-To";
  25. char t_sender[]         = "Sender";
  26. char t_followupto[]     = "Followup-To";
  27. char t_datereceived[]     = "Date-Received";
  28. char t_expires[]     = "Expires";
  29. char t_references[]     = "References";
  30. char t_control[]     = "Control";
  31. char t_distribution[]     = "Distribution";
  32. char t_organization[]     = "Organization";
  33. char t_lines[]         = "Lines";
  34.  
  35. typedef enum ft
  36. {
  37.     f_control, f_date, f_datereceived, f_distribution,
  38.     f_expires, f_followupto, f_from, f_lines, f_messageid,
  39.     f_newsgroups, f_organization, f_path, f_postversion,
  40.     f_references, f_relayversion, f_replyto, f_sender,
  41.     f_subject
  42. }
  43.  
  44.  
  45. ftype;
  46.  
  47. typedef struct field {
  48.     char *f_name;
  49.     ftype    f_type;
  50. } field;
  51.  
  52. static field fields[] = 
  53. {
  54.     { t_control,     f_control     },
  55.     { t_date,         f_date         },
  56.     { t_datereceived,     f_datereceived     },
  57.     { t_distribution,     f_distribution     },
  58.     { t_expires,     f_expires     },
  59.     { t_followupto,     f_followupto     },
  60.     { t_from,         f_from         },
  61.     { t_lines,     f_lines         },
  62.     { t_messageid,     f_messageid     },
  63.     { t_newsgroups,     f_newsgroups     },
  64.     { t_organization,     f_organization     },
  65.     { t_path,         f_path         },
  66.     { t_postversion,     f_postversion     },
  67.     { t_references,     f_references     },
  68.     { t_relayversion,     f_relayversion     },
  69.     { t_replyto,     f_replyto     },
  70.     { t_sender,     f_sender     },
  71.     { t_subject,     f_subject     }
  72. };
  73.  
  74.  
  75. char *weekdays[7] = 
  76. {
  77.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  78. };
  79.  
  80.  
  81. char *months[12] = 
  82. {
  83.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  84.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  85. };
  86.  
  87.  
  88. static
  89. fieldcmp(a, b)
  90. field *a, *b;
  91. {
  92.     return CMP(a->f_name, b->f_name);
  93. }
  94.  
  95.  
  96. /*
  97.  * extract headers from file,
  98.  * position file to start of body
  99.  */
  100. gethead(f, hp)
  101. FILE *f;
  102. header *hp;
  103. {
  104.     register char *colon, *space, *s;
  105.     register field    *fp;
  106.     field        af;
  107.     char buf[BUFLEN*2];
  108.     char *hfgets();
  109.  
  110.     memset((char *) hp, 0, sizeof(header));
  111.     while (hfgets(buf, sizeof(buf), f)) {
  112.         if (buf[0] == '\n')
  113.             return;
  114.         if (isupper(buf[0]) && (colon = strchr(buf, ':')) &&
  115.             (space = strchr(buf, ' ')) && (colon + 1 == space)) {
  116.             *colon = '\0';
  117.             af.f_name = buf;
  118.             fp = (field * )bsearch((char *)&af, (char *)fields,
  119.                 sizeof fields/sizeof fields[0], sizeof fields[0],
  120.                 fieldcmp);
  121.             *colon = ':';
  122.         } else
  123.             fp = NULL;
  124.         if (!fp)
  125.             if (hp->h_others)
  126.                 hp->h_others = catstr(hp->h_others, buf);
  127.             else
  128.                 hp->h_others = newstr(buf);
  129.         else {
  130.             if (colon = strchr(space + 1, '\n'))
  131.                 *colon = '\0';
  132.             s = newstr(space + 1);
  133.             switch (fp->f_type) {
  134.             case f_control:        
  135.                 hp->h_control = s;    
  136.                 break;
  137.             case f_date:        
  138.                 hp->h_date = s;        
  139.                 break;
  140.             case f_datereceived:    
  141.                 hp->h_datereceived = s;    
  142.                 break;
  143.             case f_distribution:    
  144.                 hp->h_distribution = s;    
  145.                 break;
  146.             case f_expires:        
  147.                 hp->h_expires = s;    
  148.                 break;
  149.             case f_followupto:    
  150.                 hp->h_followupto = s;    
  151.                 break;
  152.             case f_from:        
  153.                 hp->h_from = s;        
  154.                 break;
  155.             case f_lines:        
  156.                 hp->h_lines = s;    
  157.                 break;
  158.             case f_messageid:    
  159.                 hp->h_messageid = s;    
  160.                 break;
  161.             case f_newsgroups:    
  162.                 hp->h_newsgroups = s;    
  163.                 break;
  164.             case f_organization:    
  165.                 hp->h_organisation = s;    
  166.                 break;
  167.             case f_path:        
  168.                 hp->h_path = s;        
  169.                 break;
  170.             case f_postversion:    
  171.                 hp->h_postversion = s;    
  172.                 break;
  173.             case f_references:    
  174.                 hp->h_references = s;    
  175.                 break;
  176.             case f_relayversion:    
  177.                 hp->h_relayversion = s;    
  178.                 break;
  179.             case f_replyto:        
  180.                 hp->h_replyto = s;    
  181.                 break;
  182.             case f_sender:        
  183.                 hp->h_sender = s;    
  184.                 break;
  185.             case f_subject:        
  186.                 hp->h_subject = s;    
  187.                 break;
  188.             }
  189.         }
  190.     }
  191. }
  192.  
  193.  
  194. /*
  195.  * put headers to file
  196.  */
  197. puthead(hp, f, com)
  198. header *hp;
  199. FILE *f;
  200. pheadcom com;            /* actually ignored now */
  201. {
  202.     register char *s;
  203.     char *getunique();
  204.     extern char *getenv();
  205.  
  206.     if (hp->h_relayversion)
  207.         (void) fprintf(f, hform, t_relayversion, hp->h_relayversion);
  208.  
  209.     if (hp->h_postversion)
  210.         (void) fprintf(f, hform, t_postversion, hp->h_postversion);
  211.  
  212.     if (hp->h_from)
  213.         (void) fprintf(f, hform, t_from, hp->h_from);
  214.  
  215.     if (hp->h_date)
  216.         (void) fprintf(f, hform, t_date, hp->h_date);
  217.  
  218.     if (hp->h_newsgroups)
  219.         (void) fprintf(f, hform, t_newsgroups, hp->h_newsgroups);
  220.  
  221.     if (hp->h_subject)
  222.         (void) fprintf(f, hform, t_subject, hp->h_subject);
  223.  
  224.     if (hp->h_messageid)
  225.         (void) fprintf(f, hform, t_messageid, hp->h_messageid);
  226.  
  227.     if (hp->h_path)
  228.         (void) fprintf(f, hform, t_path, hp->h_path);
  229.  
  230.     /* optional */
  231.  
  232.     if (hp->h_replyto)
  233.         (void) fprintf(f, hform, t_replyto, hp->h_replyto);
  234.  
  235.     if (hp->h_sender)
  236.         (void) fprintf(f, hform, t_sender, hp->h_sender);
  237.  
  238.     if (hp->h_followupto)
  239.         (void) fprintf(f, hform, t_followupto, hp->h_followupto);
  240.  
  241.     if (hp->h_datereceived)
  242.         (void) fprintf(f, hform, t_datereceived, hp->h_datereceived);
  243.  
  244.     if (hp->h_expires)
  245.         (void) fprintf(f, hform, t_expires, hp->h_expires);
  246.  
  247.     if (hp->h_references)
  248.         (void) fprintf(f, hform, t_references, hp->h_references);
  249.  
  250.     if (hp->h_control)
  251.         (void) fprintf(f, hform, t_control, hp->h_control);
  252.  
  253.     if (hp->h_distribution)
  254.         (void) fprintf(f, hform, t_distribution, hp->h_distribution);
  255.  
  256.     if (hp->h_organisation)
  257.         (void) fprintf(f, hform, t_organization, hp->h_organisation);
  258.  
  259.     if (hp->h_lines)
  260.         (void) fprintf(f, hform, t_lines, hp->h_lines);
  261.  
  262.     if (hp->h_others)
  263.         fputs(hp->h_others, f);
  264. }
  265.  
  266.  
  267. /*
  268.  * free all strings allocated to header
  269.  */
  270. freehead(hp)
  271. register header *hp;
  272. {
  273.     if (hp->h_relayversion)    
  274.         free(hp->h_relayversion);
  275.     if (hp->h_postversion)    
  276.         free(hp->h_postversion);
  277.     if (hp->h_from)        
  278.         free(hp->h_from);
  279.     if (hp->h_date)        
  280.         free(hp->h_date);
  281.     if (hp->h_newsgroups)    
  282.         free(hp->h_newsgroups);
  283.     if (hp->h_subject)    
  284.         free(hp->h_subject);
  285.     if (hp->h_messageid)    
  286.         free(hp->h_messageid);
  287.     if (hp->h_path)        
  288.         free(hp->h_path);
  289.     if (hp->h_replyto)    
  290.         free(hp->h_replyto);
  291.     if (hp->h_sender)    
  292.         free(hp->h_sender);
  293.     if (hp->h_followupto)    
  294.         free(hp->h_followupto);
  295.     if (hp->h_datereceived)    
  296.         free(hp->h_datereceived);
  297.     if (hp->h_expires)    
  298.         free(hp->h_expires);
  299.     if (hp->h_references)    
  300.         free(hp->h_references);
  301.     if (hp->h_control)    
  302.         free(hp->h_control);
  303.     if (hp->h_distribution)    
  304.         free(hp->h_distribution);
  305.     if (hp->h_organisation)    
  306.         free(hp->h_organisation);
  307.     if (hp->h_lines)        
  308.         free(hp->h_lines);
  309.     if (hp->h_others)    
  310.         free(hp->h_others);
  311. }
  312.  
  313.  
  314. /*
  315.  * hfgets is like fgets, but deals with continuation lines.
  316.  * It also ensures that even if a line that is too long is
  317.  * received, the remainder of the line is thrown away
  318.  * instead of treated like a second line.
  319.  */
  320. char *
  321. hfgets(buf, len, fp)
  322. char *buf;
  323. int len;
  324. FILE *fp;
  325. {
  326.     register int c;
  327.     register char *cp, *tp;
  328.  
  329.     if ((cp = fgets(buf, len, fp)) == NULL)
  330.         return NULL;
  331.  
  332.     if (*cp == '\n')
  333.         return cp;
  334.  
  335.     tp = cp + strlen(cp);
  336.     if (tp[-1] != '\n') {
  337.         /* Line too long - part read didn't fit into a newline */
  338.         while ((c = getc(fp)) != '\n' && c != EOF)
  339.             ;
  340.     } else
  341.         *--tp = '\0';    /* clobber newline */
  342.  
  343.     while ((c = getc(fp)) == ' ' || c == '\t') {
  344.         /* Continuation line. */
  345.         while ((c = getc(fp)) == ' ' || c == '\t')
  346.             ;
  347.         if (tp - cp < len) {
  348.             *tp++ = ' ';
  349.             *tp++ = c;
  350.         }
  351.         while ((c = getc(fp)) != '\n' && c != EOF)
  352.             if (tp - cp < len)
  353.                 *tp++ = c;
  354.     }
  355.     *tp++ = '\n';
  356.     *tp++ = '\0';
  357.     if (c != EOF)
  358.         ungetc(c, fp);    /* push back first char of next header */
  359.     return cp;
  360. }
  361.  
  362.  
  363.  
  364. /*
  365.  * ascii to time
  366.  * return 0L on error
  367.  */
  368. long
  369. atot(s)
  370. char *s;
  371. {
  372.     struct timeb ftnow;
  373.     extern long getdate();
  374.  
  375.     ftime(&ftnow);
  376.     return getdate(s, &ftnow);
  377. }
  378.